package com.ddc.exoplayertest;

import android.net.Uri;

import com.google.android.exoplayer2.upstream.DataSink;
import com.google.android.exoplayer2.upstream.DataSpec;
import com.google.android.exoplayer2.upstream.crypto.AesCipherDataSink;
import com.google.android.exoplayer2.util.Util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

import timber.log.Timber;

/**
 * AES加密解密帮助类
 * Created by 汪常伟 on 2017/9/4.
 */

public class AESHelper {
    public static final String VIPARA = "1231231241241243";
    private static final String TAG = AESHelper.class.getSimpleName();

    /**
     * 初始化 AES Cipher
     *
     * @param sKey
     * @param cipherMode
     * @return
     */
    private static Cipher initAESCipher(String sKey, int cipherMode) {
        //创建Key gen
        KeyGenerator keyGenerator = null;
        Cipher cipher = null;
        try {
            IvParameterSpec zeroIv = new IvParameterSpec(VIPARA.getBytes());
            SecretKeySpec key = new SecretKeySpec(sKey.getBytes(), "AES");
            cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            cipher.init(cipherMode, key, zeroIv);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        } catch (InvalidKeyException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        } catch (InvalidAlgorithmParameterException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return cipher;
    }



    public static void encryptFile(String key, String sourceFilePath, String destFilePath) {
        try {
            // Fully read the input stream.
            InputStream inputStream = new FileInputStream(new File(sourceFilePath));
            byte[] inputStreamBytes = Util.toByteArray(inputStream);
            inputStream.close();
            File destFile = new File(destFilePath);
            destFile.createNewFile();

            // Create a sink that will encrypt and write to file.
            AesCipherDataSink encryptingDataSink = new AesCipherDataSink(
                    Util.getUtf8Bytes(key),
                    new DataSink() {
                        private FileOutputStream fileOutputStream;
                        @Override
                        public void open(DataSpec dataSpec) throws IOException {
                            fileOutputStream = new FileOutputStream(destFile);
                        }
                        @Override
                        public void write(byte[] buffer, int offset, int length) throws IOException {
                            fileOutputStream.write(buffer, offset, length);
                        }
                        @Override
                        public void close() throws IOException {
                            fileOutputStream.close();
                        }
                    });

            // Push the data through the sink, and close everything.
            encryptingDataSink.open(new DataSpec(Uri.fromFile(destFile)));
            encryptingDataSink.write(inputStreamBytes, 0, inputStreamBytes.length);
            encryptingDataSink.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void decryptFile(String key, String sourceFilePath, String destFilePath) {
        try {
            // Fully read the input stream.
            InputStream inputStream = new FileInputStream(new File(sourceFilePath));
            byte[] inputStreamBytes = Util.toByteArray(inputStream);
            inputStream.close();
            File destFile = new File(destFilePath);
            destFile.createNewFile();

            // Create a sink that will encrypt and write to file.
            AesCipherDataDecrypt AesCipherDataUtils = new AesCipherDataDecrypt(
                    Util.getUtf8Bytes(key),
                    new DataSink() {
                        private FileOutputStream fileOutputStream;
                        @Override
                        public void open(DataSpec dataSpec) throws IOException {
                            fileOutputStream = new FileOutputStream(destFile);
                        }
                        @Override
                        public void write(byte[] buffer, int offset, int length) throws IOException {
                            fileOutputStream.write(buffer, offset, length);
                        }
                        @Override
                        public void close() throws IOException {
                            fileOutputStream.close();
                        }
                    });

            // Push the data through the sink, and close everything.
            AesCipherDataUtils.open(new DataSpec(Uri.fromFile(destFile)));
            AesCipherDataUtils.write(inputStreamBytes, 0, inputStreamBytes.length);
            AesCipherDataUtils.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}
